#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QFileDialog>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->processButton->setEnabled(false);

    ui_canny = new canny_parameter;
    ui_sobel = new sobel_parameter;

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_openButton_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(this,
           tr("Open Image"), ".", tr("Image Files (*.png *.jpg *.bmp)"));
       m_originalImg = cv::imread(fileName.toUtf8().data());//,CV_LOAD_IMAGE_GRAYSCALE);

       if(m_originalImg.data) {
           ui->processButton->setEnabled(true);
           this->displayImage(m_originalImg);
       }
}

void MainWindow::on_processButton_clicked()
{
    if(ui->Filter_comboBox->currentText() == "Sobel"){
        this->processSobel();
    }
    else {
        if(ui->Filter_comboBox->currentText() == "Canny"){
            this->processCanny();
        }
    }
}

void MainWindow::on_setParameter_clicked()
{
    if(ui->Filter_comboBox->currentText() == "Sobel"){
        ui_sobel->show();
    }
    else {
        if(ui->Filter_comboBox->currentText() == "Canny"){
            ui_canny->show();
        }
    }
}

void MainWindow::processCanny()
{
    cv::Mat image_CV_8U;
    cv::cvtColor(m_originalImg, image_CV_8U, CV_BGR2GRAY);//CV_BGR2GRAY);

    double threshold1 = ui_canny->getLowThreshold();
    double threshold2 = ui_canny->getHighThreshold();

    int filter_size = ui_canny->getFilterSize();

    bool l2norm = ui_canny->getL2Norm();

    cv::Size ksize(filter_size,filter_size);

    if(ui_canny->getBlur()){
        cv::blur(image_CV_8U,image_CV_8U, ksize);
    }

    cv::Canny(image_CV_8U,image_CV_8U,threshold1,threshold2,filter_size,l2norm);

    cv::threshold(image_CV_8U,image_CV_8U, 200.0, 255.0, CV_THRESH_BINARY_INV);

    cv::namedWindow( "canny_operator", CV_WINDOW_AUTOSIZE);
    cv::imshow("canny_operator",image_CV_8U);
}

void MainWindow::processSobel(){
    cv::Mat image_CV_8U;
    cv::Mat image_CV_32F;
    cv::cvtColor(m_originalImg, image_CV_8U, CV_BGR2GRAY);//CV_BGR2GRAY);
    image_CV_8U.convertTo(image_CV_32F,CV_64F);

    double delta = 0;
    delta = ui_sobel->get_verschiebung();
    cv::Point anchor = cv::Point(-1,-1);

    // 3x3 horizontal
    cv::Mat hkernel = (cv::Mat_<double>(3,3) <<  1,  2,  1,
                                                 0,  0,  0,
                                                -1, -2, -1);
    // 3x3 vertikal
    cv::Mat vkernel = (cv::Mat_<double>(3,3) <<  1,  0, -1,
                                                 2,  0, -2,
                                                 1,  0, -1);
    //int scale = ui_sobel->get_skalierung();
    //image_CV_32F = image_CV_32F / (float) scale;

    // 5x5 horizontal
    /*cv::Mat hkernel = (cv::Mat_<double>(5,5) <<  -1, -4, -6, -4, -1,
                                                 -2, -8, -12, -8, -2,
                                                 0, 0, 0, 0, 0,
                                                 2, 8, 12, 8, 2,
                                                 1, 4, 6, 4, 1);*/

    //cv::Matx33f hkernel = cv::Matx33f(1.0,0.0,-1.0,2.0,0.0,-2.0,1.0,0.0,-1.0);

    // horizontal = 1, vertikal = 2, beides = 3
    int box = ui_sobel->get_hvcheckbox();
    if(box == 1){
        // horizontal
        cv::filter2D(image_CV_32F, image_CV_32F, -1, hkernel, anchor, delta);
    }
    if(box == 2){
        // vertikal
        cv::filter2D(image_CV_32F, image_CV_32F, -1, vkernel, anchor, delta);
    }
    if(box == 3){
        cv::Mat himage_CV_8U;
        cv::Mat vimage_CV_8U;
        cv::filter2D(image_CV_32F, himage_CV_8U, -1, hkernel, anchor, delta);
        cv::filter2D(image_CV_32F, vimage_CV_8U, -1, vkernel, anchor, delta);

        cv::magnitude(vimage_CV_8U,himage_CV_8U,image_CV_32F);
    }

    int scale = ui_sobel->get_skalierung();
    image_CV_32F = image_CV_32F / (float) scale;

    cv::namedWindow( "sobel_operator", CV_WINDOW_AUTOSIZE);
    cv::imshow("sobel_operator",image_CV_32F);

    // 5x5 vertikal
    /*cv::Mat kernel = (cv::Mat_<double>(5,5) <<  1.0, 2.0,  0.0, -2.0, -1.0,
                                                4.0, 8.0,  0.0, -8.0, -4.0,
                                                6.0, 12.0, 0.0, -12.0, -6.0,
                                                4.0, 8.0,  0.0, -8.0, -4.0,
                                                1.0, 2.0,  0.0, -2.0, -1.0);*/
}

void MainWindow::displayImage(cv::Mat image)
{
    // Erzeuge ein Qt image
    //QImage img = QImage((uchar*) image.data, image.cols, image.rows, image.step, QImage::Format_Indexed8);
    QImage img = QImage((uchar*) image.data, image.cols, image.rows, image.step, QImage::Format_RGB888);//.scaledToWidth(ui->processImgLabel->width());

    if(ui->processImgLabel) {
        // Erzeuge eine Pixmap
        QPixmap pixmap = QPixmap::fromImage(img);

        // Zeige Pixmap im Label an
        ui->processImgLabel->setPixmap(pixmap);

        // Groessenanpassung des Labels fuer das Bild durchfuehren
        ui->processImgLabel->resize(ui->processImgLabel->pixmap()->size());
    }
}
